package com.test30_IO流;

import org.junit.Test;

import java.io.*;

/**
 * 文件拷贝
 */
public class Demo07_FileCopy {

    /**
     * 单个文件拷贝
     */
    @Test
    public void test1() throws Exception {
        String inPath = "F:\\muyan.txt";
        String outPath = "F:\\yootk.txt";
        System.out.println(new CopyUtil(inPath, outPath).copy());
    }

    /**
     * 实现目录拷贝
     */
    @Test
    public void test2() throws Exception {
        String inPath = "F:\\muyan";
        String outPath = "F:\\yootk";
        System.out.println(new CopyUtil(inPath, outPath).copy());
    }
}

interface ICopy {
    /** 拷贝操作 */
    public long copy() throws IOException;
}

class CopyUtil implements ICopy {
    private File inFile;    // 输入文件路径
    private File outFile;   // 输出文件路径
    private File currentFile;   // 进行递归操作时，所实现的当前文件路径的存储

    public CopyUtil(String[] args) {
        if (args.length != 2) {
            System.out.println("【ERROR】程序拷贝命令输入的参数不足，无法执行");
            System.out.println("试用参考：java YootkDemo 源文件路径 目标文件路径");
            System.exit(1); // 程序退出
        }
        this.inFile = new File(args[0]);
        this.outFile = new File(args[1]);
    }

    public CopyUtil(String inPath, String outPath) {
        this.inFile = new File(inPath);
        this.outFile = new File(outPath);
    }

    /**
     * 实现文件的拷贝处理操作
     * @return 拷贝文件所花费时间
     */
    @Override
    public long copy() throws IOException {
        long start = System.currentTimeMillis();    // 获取开始时间
        if (!this.outFile.exists()) {
            if (this.outFile.isDirectory()) {
                this.outFile.mkdirs();  // 创建目录
            }
            if (this.outFile.isFile()) {
                this.outFile.getParentFile().mkdirs();  // 创建父目录
            }
        }
        if (this.inFile.isDirectory()) {
            this.copyHandle(this.inFile);   // 递归操作
        } else {
            this.copyFile(this.inFile);
        }
        long end = System.currentTimeMillis();  // 获取结束时间
        return end - start;
    }

    /** 实现具体的拷贝处理 */
    private void copyHandle(File file) throws IOException {
        if (file.isDirectory()) {
            File[] list = file.listFiles();
            if (list != null) {
                for (File temp : list) {
                    this.copyHandle(temp);
                }
            }
        } else {
            if (file.isFile()) {
                this.copyFile(file);
            }
        }
    }

    private void copyFile(File inputFile) throws IOException {
        InputStream input = null;
        OutputStream output = null;
        try {
            input = new FileInputStream(inputFile);
            if (this.inFile.isDirectory()) {
                String outFileName = inputFile.getPath().replace(this.inFile.getPath(), "") ;
                File outputFile = new File(this.outFile, outFileName) ;
                if (!outputFile.getParentFile().exists()) {     // 不存在输出的目录
                    outputFile.getParentFile().mkdirs() ;   // 创建相应的输出目录
                }
                output = new FileOutputStream(outputFile) ; // 字节输出流
                byte[] data = new byte[1024];
                int len = 0;
                while ((len = input.read(data)) != -1) {
                    output.write(data, 0, len);
                }
            } else if (this.inFile.isFile()) {
                output = new FileOutputStream(this.outFile);
                byte[] data = new byte[1024];
                int len = 0;
                while ((len = input.read(data)) != -1) {
                    output.write(data, 0, len);
                }
            }
        } finally {
            if (input != null) {
                input.close();
            }
            if (output != null) {
                output.close();
            }
        }
    }
}
